/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date: 2010-03-31 22:40:27 +0800 (周三, 31 三月 2010) $
Version:   $Revision: 21975 $ 
 
Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

// Blueberry
#include <berryISelectionService.h>
#include <berryIWorkbenchWindow.h>

// Qmitk
#include "WxLiverAnalysisView.h"
#include "QmitkStdMultiWidget.h"

// Qt
#include <QMessageBox>



#include <qaction.h>
//#include "QmitkTreeNodeSelector.h"
#include "mitkStatusBar.h"
#include "mitkProgressBar.h"
#include "vtkImageData.h"
#include "vtkInformation.h"
#include "mitkPointSet.h"
#include "vtkvmtkVesselnessMeasureImageFilter.h"
#include "vtkDataObject.h"
#include "QmitkCommonFunctionality.h"
#include "vtkvmtkITKImageToImageFilterFF.h"
#include "vtkvmtkSatoVesselnessMeasureImageFilter.h"
#include "vtkImageChangeInformation.h"
#include "vtkImageCast.h"
#include <qlineedit.h>
#include <qslider.h>
#include <qgroupbox.h>
#include <qcheckbox.h>
#include <QIntValidator>
#include <qtoolbutton.h>
#include <qobject.h>
#include <qapplication.h>
#include <qcursor.h>
#include <qpushbutton.h>
//#include <QSpinBox.h>
#include <vtkLinearTransform.h>
#include <string.h>
#include <mitkGeometry3D.h>
#include "mitkGlobalInteraction.h"
#include "vtkIdList.h"
#include "vtkImageThreshold.h"
#include "vtkImageShiftScale.h"
#include "vtkvmtkFastMarchingUpwindGradientImageFilter.h"
#include "vtkvmtkCollidingFrontsImageFilter.h"
#include "vtkImageMathematics.h"
//#include "Image.h"
#include "vtkPolyData.h"
#include "vtkMarchingCubes.h"
#include "vtkReverseSense.h"
#include "vtkTransformPolyDataFilter.h"
#include "vtkPolyDataNormals.h"
#include "vtkStripper.h"
#include "mitkSurface.h"
//#include "QLineEdit.h"
#include "vtkTransform.h"
#include "vtkMatrix4x4.h"
#include "vtkvmtkGeodesicActiveContourLevelSetImageFilter.h"

#include "vtkWindowedSincPolyDataFilter.h"
#include "vtkLinearTransform.h"

//#include "mitkVector.h.h"
#include <qmessagebox.h>
#include "vtkvmtkCapPolyData.h"
#include "vtkvmtkPolyDataCenterlines.h"
#include "vtkImageThreshold.h"
#include "vtkImageShiftScale.h"
#include "vtkvmtkFastMarchingUpwindGradientImageFilter.h"
#include "vtkPolyData.h"
#include "mitkProperties.h"
#include "mitkImageSource.h"
#include "mitkDataNode.h"
#include "vtkvmtkCenterlineBranchExtractor.h"
#include "vtkvmtkPolyBallModeller.h"
#include "vtkTriangleFilter.h"
#include "vtkLinearSubdivisionFilter.h"
#include "vtkCleanPolyData.h"

#include "vtkMath.h"
#include "vtkCellData.h"
#include "vtkCell.h"
#include "vtkCellArray.h"
#include "vtkvmtkFastMarchingUpwindGradientImageFilter.h"
#include "vtkvmtkCollidingFrontsImageFilter.h"
#include "vtkMatrix4x4.h"
#include "vtkvmtkGeodesicActiveContourLevelSetImageFilter.h"
#include "vtkTransformPolyDataFilter.h"
#include "vtkLinearTransform.h"
#include "vtkPolyDataNormals.h"
//#include "mitkVector.h.h"
#include "vtkTransformPolyDataFilter.h"
#include "vtkvmtkPolyDataCenterlineGroupsClipper.h"
#include "vtkImageGaussianSmooth.h"
#include "mitkImageToSurfaceFilter.h"

#include "mitkImageCast.h"
#include "mitkITKImageImport.h"

// ITK includes (general)
#include <itkVectorImage.h>

// Morphological Operations
#include <itkBinaryBallStructuringElement.h>
#include <itkGrayscaleDilateImageFilter.h>
#include <itkGrayscaleErodeImageFilter.h>
#include <itkGrayscaleMorphologicalOpeningImageFilter.h>
#include <itkGrayscaleMorphologicalClosingImageFilter.h>

// Smoothing
#include <itkMedianImageFilter.h>
#include <itkDiscreteGaussianImageFilter.h>
//#include <itkTotalVariationDenoisingImageFilter.h>

// Threshold
#include <itkBinaryThresholdImageFilter.h>

// Inversion
#include <itkInvertIntensityImageFilter.h>

// Derivatives
#include <itkGradientMagnitudeRecursiveGaussianImageFilter.h>
#include <itkLaplacianImageFilter.h>
#include <itkSobelEdgeDetectionImageFilter.h>

// Resampling
#include <itkResampleImageFilter.h>
#include <itkNearestNeighborInterpolateImageFunction.h>

// Image Arithmetics
#include <itkAddImageFilter.h>
#include <itkSubtractImageFilter.h>
#include <itkMultiplyImageFilter.h>
#include <itkDivideImageFilter.h>

// Boolean operations
#include <itkOrImageFilter.h>
#include <itkAndImageFilter.h>
#include <itkXorImageFilter.h>
#include <vtkSmoothPolyDataFilter.h>
#include <mitkBaseRenderer.h>
#include <mitkColorProperty.h>
#include <vtkvmtkCurvesLevelSetImageFilter.h>
#include <vtkvmtkCollidingFrontsImageFilter.h>
#include <vtkCleanPolyData.h>
#include <vtkSplineFilter.h>
#include "vtkSurfaceReconstructionFilter.h"
#include <mitkSurfaceToImageFilter.h>
#include "vtkPolyDataConnectivityFilter.h"

#include "vtkCellDataToPointData.h"

#include "mitkNodePredicateDataType.h"

// MITK
#include "mitkImageAccessByItk.h"
#include "mitkITKImageImport.h"
#include "mitkProperties.h"
#include "mitkColorProperty.h"

// ITK
#include <itkConnectedThresholdImageFilter.h>


#include <vtkDecimatePro.h>


const std::string WxLiverAnalysisView::VIEW_ID = "Wx.301.views.wxliveranalysis";

WxLiverAnalysisView::WxLiverAnalysisView()
: QmitkFunctionality()
, m_SelectedImageNode(NULL)
,m_SelectedsurfaceeNode(NULL)
, m_Controls( 0 )
,mask(false)
, m_MultiWidget( NULL )
{

}

WxLiverAnalysisView::~WxLiverAnalysisView()
{

}
void WxLiverAnalysisView::CreateQtPartControl( QWidget *parent )
{
  // build up qt view, unless already done
  if ( !m_Controls )
  {
    // create GUI widgets from the Qt Designer's .ui file
    m_Controls = new Ui::WxLiverAnalysisViewControls;
    m_Controls->setupUi( parent );
 
    //////////////////////////////////AddPointInteractor();

            // let the point set widget know about the multi widget (crosshair updates)
            m_Controls->lstPoints->SetMultiWidget( m_MultiWidget );

            // create a new DataNode containing a PointSet with some interaction
            m_SourcePointSet = mitk::PointSet::New();

            m_SourcePointSetNode = mitk::DataNode::New();
            m_SourcePointSetNode->SetData( m_SourcePointSet );
            m_SourcePointSetNode->SetName("seed points for Source");
            m_SourcePointSetNode->SetProperty("helper object", mitk::BoolProperty::New(true) );
            m_SourcePointSetNode->SetProperty("lable", mitk::StringProperty::New("Point") );
            m_SourcePointSetNode->SetProperty("layer", mitk::IntProperty::New(1024) );

            // add the pointset to the data tree (for rendering and access by other modules)
            GetDefaultDataStorage()->Add( m_SourcePointSetNode );

            // tell the GUI widget about out point set
            m_Controls->lstPoints->SetPointSetNode( m_SourcePointSetNode );
   //===========================================================================
            //////////////////////////////////AddPointInteractor();

            // let the point set widget know about the multi widget (crosshair updates)
            m_Controls->lstPoints_3->SetMultiWidget( m_MultiWidget );

            // create a new DataNode containing a PointSet with some interaction
            m_SourcePointSet_re = mitk::PointSet::New();

            m_SourcePointSetNode_re = mitk::DataNode::New();
            m_SourcePointSetNode_re->SetData( m_SourcePointSet_re );
            m_SourcePointSetNode_re->SetName("seed points for Source_re");
            m_SourcePointSetNode_re->SetProperty("helper object", mitk::BoolProperty::New(true) );
            m_SourcePointSetNode_re->SetProperty("layer", mitk::IntProperty::New(1024) );

            // add the pointset to the data tree (for rendering and access by other modules)
            GetDefaultDataStorage()->Add( m_SourcePointSetNode_re );

            // tell the GUI widget about out point set
            m_Controls->lstPoints_3->SetPointSetNode( m_SourcePointSetNode_re );
            //===========================================================================

            // let the point set widget know about the multi widget (crosshair updates)
            m_Controls->lstPoints_4->SetMultiWidget( m_MultiWidget );

            // create a new DataNode containing a PointSet with some interaction
            m_TargetPointSet_re = mitk::PointSet::New();

            m_TargetPointSetNode_re = mitk::DataNode::New();
            m_TargetPointSetNode_re->SetData( m_TargetPointSet_re );
            m_TargetPointSetNode_re->SetName("seed points for Target_re");
            m_TargetPointSetNode_re->SetProperty("helper object", mitk::BoolProperty::New(true) );
            m_TargetPointSetNode_re->SetProperty("layer", mitk::IntProperty::New(1024) );

            // add the pointset to the data tree (for rendering and access by other modules)
            GetDefaultDataStorage()->Add( m_TargetPointSetNode_re );

            // tell the GUI widget about out point set
            m_Controls->lstPoints_4->SetPointSetNode( m_TargetPointSetNode_re );


    connect( m_Controls->btnPerformImageProcessing, SIGNAL(clicked()), this, SLOT(DoImageProcessing()) );
    connect( m_Controls->pushButtonVesselRe, SIGNAL(clicked()), this, SLOT(DoVesselRe()) );
    connect( m_Controls->pushButton_3, SIGNAL(clicked()), this, SLOT(acseg()) );

    m_SelectedImageNode = mitk::DataStorageSelection::New(this->GetDefaultDataStorage(), false);
    m_SelectedsurfaceeNode = mitk::DataStorageSelection::New(this->GetDefaultDataStorage(), false);
    m_Controls->pushButton_3->setEnabled(false);
  }
}


void WxLiverAnalysisView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget)
{
  vtkObject::GlobalWarningDisplayOff();
  m_MultiWidget = &stdMultiWidget;
  m_Controls->lstPoints->SetMultiWidget( &stdMultiWidget );
  m_Controls->lstPoints_3->SetMultiWidget( &stdMultiWidget );
  m_Controls->lstPoints_4->SetMultiWidget( &stdMultiWidget );
}

void WxLiverAnalysisView::Deactivated()
{
    m_Controls->lstPoints->SetAddPointToggle(false);
    m_Controls->lstPoints_3->SetAddPointToggle(false);
    m_Controls->lstPoints_4->SetAddPointToggle(false);
}

void WxLiverAnalysisView::StdMultiWidgetNotAvailable()
{
	//vtkObject::GlobalWarningDisplayOn();
	m_MultiWidget = NULL;
	m_Controls->lstPoints->SetMultiWidget( 0 );
	m_Controls->lstPoints_3->SetMultiWidget( 0 );
	m_Controls->lstPoints_4->SetMultiWidget( 0 );
}


void WxLiverAnalysisView::OnSelectionChanged( std::vector<mitk::DataNode*> nodes )
{ 
  // iterate all selected objects, adjust warning visibility

    m_Controls->btnPerformImageProcessing->setEnabled(false);
    m_Controls->pushButtonVesselRe->setEnabled(false);


    m_Controls->pushButton_3->setEnabled(false);




    if (!nodes.empty())
    {
            m_SelectedImageNode->RemoveAllNodes();
            m_SelectedsurfaceeNode->RemoveAllNodes();
    }




    for( std::vector<mitk::DataNode*>::iterator it = nodes.begin();
            it != nodes.end();
            ++it )
    {
            mitk::DataNode::Pointer node = *it;

            if( node.IsNotNull() && dynamic_cast<mitk::Surface*>(node->GetData()) )
            {
                mitk::DataNode* surface_DataNode = *it;
                *m_SelectedsurfaceeNode = surface_DataNode;
                m_Controls->pushButtonVesselRe->setEnabled(true);
                return;

            }
    }


  for( std::vector<mitk::DataNode*>::iterator it = nodes.begin();
       it != nodes.end();
       ++it )
  {
    mitk::DataNode::Pointer node = *it;
  
    if( node.IsNotNull() && dynamic_cast<mitk::Image*>(node->GetData()) )
    {
      mitk::DataNode* image_DataNode = *it;
      *m_SelectedImageNode = image_DataNode;
      m_Controls->lblWarning->setVisible( false );
      m_Controls->btnPerformImageProcessing->setEnabled(true);
      if(mask)
      {
         m_Controls->pushButton_3->setEnabled(true);
      }
      return;
    }
  }

  m_Controls->lblWarning->setVisible( true );
}


void WxLiverAnalysisView::acseg()
{
    mitk::DataNode::Pointer node = m_SelectedImageNode->GetNode();
    //   mitk::PointSet::PointsConstIterator pointsIterator=m_PointSet->GetPointSet()->GetPoints()->Begin();

    mitk::Image* imageseed = (mitk::Image*)( node->GetData() );


    vtkImageData* image=imageseed->GetVtkImageData();


    //  vtkImageData* vtkimageseed=vtkImageData::New();

    vtkIdList*  sourceSeedIds = vtkIdList::New();
    vtkIdList*  targetSeedIds = vtkIdList::New();


    mitk::Geometry3D* imageGeometry=imageseed->GetGeometry();

    // determine a thresholding interval
    mitk::Image::IndexType seedIndex;
    mitk::Image::IndexType seedIndextarget;


    for ( mitk::PointSet::PointsConstIterator pointsIterator = m_SourcePointSet->GetPointSet()->GetPoints()->Begin();
            pointsIterator != m_SourcePointSet->GetPointSet()->GetPoints()->End();
            ++pointsIterator )
    {


            imageGeometry->WorldToIndex( pointsIterator.Value(), seedIndex);

            long* PtrSeed=(long*)seedIndex.GetIndex();

            int ASeed[3]={(int)*PtrSeed,(int)*(PtrSeed+1),(int)*(PtrSeed+2)};
            sourceSeedIds->InsertNextId(   image->ComputePointId(ASeed)  );
    }

    double Thmin,Thmax;
    Thmin=m_Controls->lineEdit_6->text().toDouble();
    Thmax=m_Controls->lineEdit_7->text().toDouble();



    vtkImageCast* ImageCast = vtkImageCast::New();
    ImageCast->SetInput(image);
    ImageCast->SetOutputScalarTypeToDouble();
    ImageCast->Update();
    image=ImageCast->GetOutput();
  

    vtkImageData *outVolumeData=ExecuteFM(ImageCast->GetOutput(),Thmin,Thmax,sourceSeedIds,targetSeedIds);
    
    double* test=outVolumeData->GetOrigin();

    vtkvmtkGeodesicActiveContourLevelSetImageFilter* levelSets=vtkvmtkGeodesicActiveContourLevelSetImageFilter::New();
    levelSets->SetFeatureImage(image);
    levelSets->SetDerivativeSigma(0.0);
    levelSets->SetAutoGenerateSpeedAdvection(1);
    levelSets->SetPropagationScaling(100);
    levelSets->SetCurvatureScaling(70);
    levelSets->SetAdvectionScaling(100);
    levelSets->SetInput(outVolumeData);
    levelSets->SetNumberOfIterations(10);
    levelSets->SetIsoSurfaceValue(0.0);
    levelSets->SetMaximumRMSError(1E-20);
    levelSets->SetInterpolateSurfaceLocation(1);
    levelSets->SetUseImageSpacing(1);
    levelSets->Update();




    mitk::Point3D ImageOrigin=imageseed->GetGeometry()->GetOrigin();
    float* PImageOrigin=ImageOrigin.Begin();
   


   vtkImageGaussianSmooth *gaussian = vtkImageGaussianSmooth::New();
   gaussian->SetInput( levelSets->GetOutput() );
   //threshold->Delete();
   gaussian->SetDimensionality( 3  );
   gaussian->SetRadiusFactor( 0.49 );
   gaussian->SetStandardDeviation( 3, 3, 3 );
   gaussian->ReleaseDataFlagOn();
   gaussian->UpdateInformation();
   gaussian->Update();
   gaussian->GetOutput()->SetOrigin(*PImageOrigin,*(PImageOrigin+1),*(PImageOrigin+2));

    vtkPolyData* outPolyData3=MarchingCubes(gaussian->GetOutput(),1);
    



    vtkPolyDataConnectivityFilter* connectivityFilter =
            vtkPolyDataConnectivityFilter::New();
    connectivityFilter->SetInput(outPolyData3);
    connectivityFilter->SetExtractionModeToLargestRegion();
    connectivityFilter->Update();
    outPolyData3=connectivityFilter->GetOutput();
    outPolyData3->Update();



	vtkTriangleFilter* triangleFilter = vtkTriangleFilter::New();
	triangleFilter->SetInput(outPolyData3);
	triangleFilter->Update();


	vtkDecimatePro* decimationFilter = vtkDecimatePro::New();
	decimationFilter->SetInput(triangleFilter->GetOutput());
	decimationFilter->SetTargetReduction(0.5);
	//        decimationFilter->SetBoundaryVertexDeletion(self.BoundaryVertexDeletion);
	decimationFilter->PreserveTopologyOn();
	decimationFilter->Update();


	vtkCleanPolyData* cleaner = vtkCleanPolyData::New();
	cleaner->SetInput(decimationFilter->GetOutput());
	cleaner->Update();



	vtkTriangleFilter* triangleFilterout = vtkTriangleFilter::New();
	triangleFilterout->SetInput(cleaner->GetOutput());
	triangleFilterout->Update();

	outPolyData3=triangleFilterout->GetOutput();
	outPolyData3->Update();



    mitk::Surface::Pointer Surbase3=mitk::Surface::New();
    Surbase3->SetVtkPolyData(outPolyData3);
    //Surbase3->SetVtkPolyData(triangleFilter->GetOutput());

    //Surbase3->SetGeometry(this->VesselImage->GetGeometry());
    Surbase3->Update();



    mitk::DataNode::Pointer outnode3=mitk::DataNode::New();
    outnode3->SetData(Surbase3);
    outnode3->SetName("vessel");
    outnode3->Update();




    GetDefaultDataStorage()->Add( outnode3, m_SelectedImageNode->GetNode());

    mitk::RenderingManager::GetInstance()->RequestUpdateAll();
	ImageCast->Delete();
	outVolumeData->Delete();
	levelSets->Delete();
	gaussian->Delete();
    connectivityFilter->Delete();
	triangleFilter->Delete();
	decimationFilter->Delete();
	triangleFilterout->Delete();
}
void WxLiverAnalysisView::DoVesselRe()
{
    m_Controls->lstPoints_3->SetAddPointToggle(false);
    m_Controls->lstPoints_4->SetAddPointToggle(false);

    mitk::DataNode::Pointer node = m_SelectedsurfaceeNode->GetNode();
    mitk::Surface* ImageSurface= dynamic_cast<mitk::Surface*>( node->GetData() );

    vtkCleanPolyData* surfaceCleaner = vtkCleanPolyData::New();
    //	surfaceCleaner->SetInput(VtkRead->GetOutput());
    surfaceCleaner->SetInput(ImageSurface->GetVtkPolyData());
    surfaceCleaner->Update();

    vtkTriangleFilter* surfaceTriangulator = vtkTriangleFilter::New();
    surfaceTriangulator->SetInput(surfaceCleaner->GetOutput());
    surfaceTriangulator->PassLinesOff();
    surfaceTriangulator->PassVertsOff();
    surfaceTriangulator->Update();

    vtkLinearSubdivisionFilter* subdiv = vtkLinearSubdivisionFilter::New();
    subdiv->SetInput(surfaceTriangulator->GetOutput());
    subdiv->SetNumberOfSubdivisions(1);
    subdiv->Update();

    vtkWindowedSincPolyDataFilter* smooth = vtkWindowedSincPolyDataFilter::New();
    smooth->SetInput(subdiv->GetOutput());
    smooth->SetNumberOfIterations(20);
    smooth->SetPassBand(0.1);
    smooth->SetBoundarySmoothing(1);
    smooth->Update();


    vtkPolyDataNormals* normals = vtkPolyDataNormals::New();
    normals->SetInput(smooth->GetOutput());
    normals->SetAutoOrientNormals(1);
    normals->SetFlipNormals(0);
    normals->SetConsistency(1);
    normals->SplittingOff();
    normals->Update();


    vtkvmtkCapPolyData* surfaceCapper = vtkvmtkCapPolyData::New();
    surfaceCapper->SetInput(normals->GetOutput());
    surfaceCapper->SetDisplacement(0.0);
    surfaceCapper->SetInPlaneDisplacement(0.0);
    surfaceCapper->Update();


    vtkPolyData* polyDataNew = vtkPolyData::New();
    polyDataNew->DeepCopy(surfaceCapper->GetOutput());
    polyDataNew->Update();


    /////////////////////////////////////////
    vtkIdList*  sourceSeedIds = vtkIdList::New();
    vtkIdList*  targetSeedIds = vtkIdList::New();


    mitk::Geometry3D* imageGeometry=ImageSurface->GetGeometry();




    for ( mitk::PointSet::PointsConstIterator pointsIterator = m_SourcePointSet_re->GetPointSet()->GetPoints()->Begin(); // really nice syntax to get an interator for all points
            pointsIterator != m_SourcePointSet_re->GetPointSet()->GetPoints()->End();
            ++pointsIterator )
    {


            mitk::Point3D seed=pointsIterator.Value();
            float* sed=(float*)seed.Begin();
            sourceSeedIds->InsertNextId(ImageSurface->GetVtkPolyData()->FindPoint((double)*sed,(double)*(sed+1),(double)*(sed+2) ));

    }

;

    for ( mitk::PointSet::PointsConstIterator pointsIterator2 = m_TargetPointSet_re->GetPointSet()->GetPoints()->Begin(); // really nice syntax to get an interator for all points
            pointsIterator2 != m_TargetPointSet_re->GetPointSet()->GetPoints()->End();
            ++pointsIterator2 )
    {


            mitk::Point3D seed=pointsIterator2.Value();
            float* sed=(float*)seed.Begin();
            targetSeedIds->InsertNextId(   ImageSurface->GetVtkPolyData()->FindPoint((double)*sed,(double)*(sed+1),(double)*(sed+2))   );


    }



    vtkPolyData* PloyCenter=computeCenterlines(ImageSurface->GetVtkPolyData(),sourceSeedIds,targetSeedIds);



    vtkvmtkCenterlineBranchExtractor* BranchExtractor=vtkvmtkCenterlineBranchExtractor::New();
    BranchExtractor->SetInput(PloyCenter);

    BranchExtractor->SetBlankingArrayName("Blanking");
    BranchExtractor->SetRadiusArrayName("MaximumInscribedSphereRadius");
    BranchExtractor->SetGroupIdsArrayName("GroupIds");
    BranchExtractor->SetCenterlineIdsArrayName("CenterlineIds");

    BranchExtractor->SetTractIdsArrayName("TractIds");

    BranchExtractor->Update();



    vtkPolyData* OutBranchPoly=vtkPolyData::New();
    OutBranchPoly->DeepCopy(BranchExtractor->GetOutput());
    OutBranchPoly->Update();


    int ModelDim[3]={64,64,64};
//  double Bounds[6]={1.0,1.0,1.0,1.0,1.0,1.0};
    vtkvmtkPolyBallModeller* modeller=vtkvmtkPolyBallModeller::New();

    modeller->SetInput( OutBranchPoly);
    modeller->SetRadiusArrayName("MaximumInscribedSphereRadius");
    modeller->UsePolyBallLineOn();
    modeller->SetSampleDimensions(ModelDim);
//	modeller->SetModelBounds(Bounds);
    modeller->SetNegateFunction(0);
    modeller->Update();



    vtkImageData* InMarching=vtkImageData::New();
    InMarching->DeepCopy(modeller->GetOutput());
    InMarching->Update();



//===========================================================
    vtkMarchingCubes* marchingCubes = vtkMarchingCubes::New();
    marchingCubes->SetInput(InMarching);
    marchingCubes->SetValue(0,1);
    marchingCubes->Update();

//	vtkPolyData* ModellerPolyData=MarchingCubes(InMarching,10.0);



    mitk::Surface::Pointer Surbasemodel=mitk::Surface::New();
    Surbasemodel->SetVtkPolyData(marchingCubes->GetOutput());
    Surbasemodel->Update();

    mitk::DataNode::Pointer outnodemodel=mitk::DataNode::New();
    outnodemodel->SetData(Surbasemodel);
    outnodemodel->SetProperty("helper object", mitk::BoolProperty::New(true) );
    outnodemodel->SetName("model data");
	outnodemodel->SetProperty("color",mitk::ColorProperty::New(1.0,0.0,0.0));
    outnodemodel->Update();

//	mitk::DataNode::Pointer parentNodemodel = mitk::DataNode::New();//m_Controls->m_ToolReferenceDataSelectionBox->GetToolManager()->GetReferenceData(0);
    node->SetFloatProperty("opacity",0.5);

    GetDefaultDataStorage()->Add( outnodemodel); // add as a child of the currently active reference image

    mitk::RenderingManager::GetInstance()->RequestUpdateAll();

    surfaceCleaner->Delete();
    surfaceTriangulator->Delete();
    subdiv->Delete();
    smooth->Delete();
    normals->Delete();
    surfaceCapper->Delete();
    polyDataNew->Delete();
    PloyCenter->Delete();
    BranchExtractor->Delete();
    OutBranchPoly->Delete();
    modeller->Delete();
    InMarching->Delete();
    marchingCubes->Delete();
}
vtkImageData* WxLiverAnalysisView::ExecuteFM(vtkImageData* image,double lowerThreshold,double higherThreshold,vtkIdList*  sourceSeedIds,vtkIdList*targetSeedIds)
{
        double*scalarRange=image->GetScalarRange();
        int* imageDimensions=image->GetDimensions();
        int maxImageDimensions=*imageDimensions;
        for(int i=0;i<2;i++)
        {
                if(*imageDimensions<*(imageDimensions+1))
                        maxImageDimensions=*(imageDimensions+1);

                imageDimensions++;
        }

        vtkImageThreshold* threshold=vtkImageThreshold::New();

        threshold->SetInput(image);
        threshold->ThresholdBetween(lowerThreshold,higherThreshold);
        threshold->ReplaceInOff();
        threshold->ReplaceOutOn();
        threshold->SetOutValue(scalarRange[0] - scalarRange[1]);
        threshold->Update();

        vtkImageData* thresholdedImage=threshold->GetOutput();

        scalarRange=thresholdedImage->GetScalarRange();

        vtkImageShiftScale* shiftScale=vtkImageShiftScale::New();
        shiftScale->SetInput(thresholdedImage);
        shiftScale->SetShift(-scalarRange[0]);
        shiftScale->SetScale(1/(scalarRange[1]-scalarRange[0]));
        shiftScale->Update();

        vtkImageData* speedImage=shiftScale->GetOutput();

        vtkvmtkFastMarchingUpwindGradientImageFilter* fastMarching=vtkvmtkFastMarchingUpwindGradientImageFilter::New();
        fastMarching->SetInput(speedImage);
        fastMarching->SetSeeds(sourceSeedIds);
       // fastMarching->GenerateGradientImageOff();
        fastMarching->GenerateGradientImageOn();
        fastMarching->SetTargetOffset(100.0);
        fastMarching->SetTargets(targetSeedIds);
        fastMarching->SetTargetReachedModeToNoTargets();
        fastMarching->Update();



        vtkImageMathematics* subtract = vtkImageMathematics::New();
        subtract->SetInput(fastMarching->GetOutput());
        subtract->SetOperationToAddConstant();
        subtract->SetConstantC(-fastMarching->GetTargetValue());
        subtract->Update();


        vtkImageData*  outVolumeData = vtkImageData::New();
        outVolumeData->DeepCopy(subtract->GetOutput());
        outVolumeData->Update();
       
		threshold->Delete();
		//thresholdedImage->Delete();
		shiftScale->Delete();
		//speedImage->Delete();
		fastMarching->Delete();
		subtract->Delete();

        return outVolumeData;
}

vtkPolyData* WxLiverAnalysisView::MarchingCubes(vtkImageData* image,double threshold)//,vtkMatrix4x4* Matrix)
{
        vtkMarchingCubes *marchingCubes=vtkMarchingCubes::New();
        marchingCubes->SetInput(image);
        marchingCubes->SetValue(0,threshold);
        marchingCubes->ComputeScalarsOn();
        marchingCubes->ComputeGradientsOn();
        marchingCubes->ComputeNormalsOn();
        marchingCubes->GetOutput()->ReleaseDataFlagOn();
        marchingCubes->Update();

        vtkReverseSense* reverser = vtkReverseSense::New();
        reverser->SetInput(marchingCubes->GetOutput());
        reverser->ReverseNormalsOn();
        reverser->GetOutput()->ReleaseDataFlagOn();
        reverser->Update();

        vtkPolyData* correctedOutput = reverser->GetOutput();


        vtkTransform* transformIJKtoRAS=vtkTransform::New();
        //   transformIJKtoRAS->SetMatrix(Matrix);

        vtkTransformPolyDataFilter* transformer = vtkTransformPolyDataFilter::New();
        transformer->SetInput(correctedOutput);
        transformer->SetTransform(transformIJKtoRAS);
        transformer->GetOutput()->ReleaseDataFlagOn();
        transformer->Update();




        vtkPolyDataNormals* normals = vtkPolyDataNormals::New();
        normals->ComputePointNormalsOn();
        normals->SetInput(transformer->GetOutput());
        //    normals->SetInput(correctedOutput);
        normals->SetFeatureAngle(60);
        normals->SetSplitting(1);
        normals->GetOutput()->ReleaseDataFlagOn();
        normals->Update();


        vtkStripper* stripper = vtkStripper::New();
        stripper->SetInput(normals->GetOutput());
        stripper->GetOutput()->ReleaseDataFlagOff();
        stripper->Update();
        stripper->GetOutput()->Update();


        vtkPolyData* result = vtkPolyData::New();
        result->DeepCopy(stripper->GetOutput());
        result->Update();
        stripper->Delete();
		transformer->Delete();
		marchingCubes->Delete();
		reverser->Delete();
		transformIJKtoRAS->Delete();
		normals->Delete();
        return result;
}
vtkPolyData* WxLiverAnalysisView::computeCenterlines(vtkPolyData* CenterIndata,vtkIdList*  inletSeedIds,vtkIdList*  outletSeedIds )
{


        vtkvmtkPolyDataCenterlines*centerlineFilter = vtkvmtkPolyDataCenterlines::New();
        centerlineFilter->SetInput(CenterIndata);
        centerlineFilter->SetSourceSeedIds(inletSeedIds);
        centerlineFilter->SetTargetSeedIds(outletSeedIds);
        centerlineFilter->SetRadiusArrayName("MaximumInscribedSphereRadius");
        centerlineFilter->SetCostFunction("1/R");
        centerlineFilter->SetFlipNormals(0);
        centerlineFilter->SetAppendEndPointsToCenterlines(0);
        centerlineFilter->SetSimplifyVoronoi(true);
        centerlineFilter->SetCenterlineResampling(0);
        centerlineFilter->SetResamplingStepLength(1.0);
        centerlineFilter->Update();


        vtkCleanPolyData* cleaner = vtkCleanPolyData::New();
        cleaner->SetInput(centerlineFilter->GetOutput());
        cleaner->Update();


        double Length= (cleaner->GetOutput()->GetLength())/100.0;

        vtkSplineFilter* splineFilter = vtkSplineFilter::New();
        splineFilter->SetInput(cleaner->GetOutput());
        splineFilter->SetSubdivideToLength();
        splineFilter->SetLength(Length);
        splineFilter->Update();


        vtkPolyData* polyOutDataNew = vtkPolyData::New();
        polyOutDataNew->DeepCopy(splineFilter->GetOutput());
        polyOutDataNew->Update();


        return polyOutDataNew;

}
void WxLiverAnalysisView::Updataimge(vtkImageData* image)
{
    mitk::Image::Pointer outimage =mitk::Image::New();
    outimage->Initialize(image);
    outimage->SetVolume(image->GetScalarPointer());
    outimage->Update();

    mitk::DataNode::Pointer outnode=mitk::DataNode::New();
    outnode->SetData(outimage);
    outnode->SetName("test");
    outnode->Update();

    GetDefaultDataStorage()->Add( outnode );

    mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void WxLiverAnalysisView::DoImageProcessing()
{
  m_Controls->lstPoints->SetAddPointToggle(false);

  mitk::DataNode* node = m_SelectedImageNode->GetNode();

  if (!node)
  {
    // Nothing selected. Inform the user and return
    QMessageBox::information( NULL, "Region growing functionality", "Please load and select an image before region growing.");
    return;
  }

  // here we have a valid mitk::DataNode

  // a node itself is not very useful, we need its data item (the image)
  mitk::BaseData* data = node->GetData();
  if (data)
  {
    // test if this data item is an image or not (could also be a surface or something totally different)
    mitk::Image* image = dynamic_cast<mitk::Image*>( data );


      // actually perform region growing. Here we have both an image and some seed points
      AccessByItk_2( image, ItkImageProcessing, image->GetGeometry(), node ); // some magic to call the correctly templated function

    }
  }

template < typename TPixel, unsigned int VImageDimension >
void WxLiverAnalysisView::ItkImageProcessing( itk::Image< TPixel, VImageDimension >* itkImage, mitk::Geometry3D* imageGeometry, mitk::DataNode* parent )
{
  typedef itk::Image< TPixel, VImageDimension > InputImageType;
  typedef typename InputImageType::IndexType    IndexType;

  // instantiate an ITK region growing filter, set its parameters
  typedef itk::ConnectedThresholdImageFilter<InputImageType, InputImageType> RegionGrowingFilterType;
  typename RegionGrowingFilterType::Pointer regionGrower = RegionGrowingFilterType::New();
  regionGrower->SetInput( itkImage ); // don't forget this

  // determine a thresholding interval
  IndexType seedIndex;


  mitk::PointSet::PointsContainer* points = m_SourcePointSet->GetPointSet()->GetPoints();
  for ( mitk::PointSet::PointsConstIterator pointsIterator = points->Begin();
        pointsIterator != points->End();
        ++pointsIterator )
  {
    // first test if this point is inside the image at all
    if ( !imageGeometry->IsInside( pointsIterator.Value()) )
    {
      continue;
    }

    // convert world coordinates to image indices
    imageGeometry->WorldToIndex( pointsIterator.Value(), seedIndex);

    // get the pixel value at this point
  //  TPixel currentPixelValue = itkImage->GetPixel( seedIndex );

    // adjust minimum and maximum values
//    if (currentPixelValue > max)
//      max = currentPixelValue;

//    if (currentPixelValue < min)
//      min = currentPixelValue;

    regionGrower->AddSeed( seedIndex );
  }



  double min=m_Controls->lineEdit_6->text().toDouble();
  double max=m_Controls->lineEdit_7->text().toDouble();

  // set thresholds and execute filter
  regionGrower->SetLower( min );
  regionGrower->SetUpper( max );

  regionGrower->Update();

  mitk::Image::Pointer resultImage = mitk::ImportItkImage( regionGrower->GetOutput() );

  if(this->mask)
  {

      newNode->SetData( resultImage );
      newNode->SetProperty("binary", mitk::BoolProperty::New(true));
      newNode->SetProperty("name", mitk::StringProperty::New("dumb segmentation"));
      newNode->SetProperty("color", mitk::ColorProperty::New(1.0,0.0,0.0));
      newNode->SetProperty("volumerendering", mitk::BoolProperty::New(false));
      newNode->SetProperty("layer", mitk::IntProperty::New(1));
      newNode->SetProperty("opacity", mitk::FloatProperty::New(0.5));
      mitk::RenderingManager::GetInstance()->RequestUpdateAll();
      return;
  }

  newNode = mitk::DataNode::New();
  newNode->SetData( resultImage );

  // set some properties
  newNode->SetProperty("binary", mitk::BoolProperty::New(true));
  newNode->SetProperty("name", mitk::StringProperty::New("dumb segmentation"));
  newNode->SetProperty("color", mitk::ColorProperty::New(1.0,0.0,0.0));
  newNode->SetProperty("volumerendering", mitk::BoolProperty::New(false));
  newNode->SetProperty("layer", mitk::IntProperty::New(1));
  newNode->SetProperty("opacity", mitk::FloatProperty::New(0.5));

  // add result to data tree
  this->GetDefaultDataStorage()->Add( newNode, parent );
  mitk::RenderingManager::GetInstance()->RequestUpdateAll();
  m_Controls->pushButton_3->setEnabled(true);
  mask=true;
}

